﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Deployment.Application;

namespace AppMain
{
    public partial class StartWindow : Form
    {
        //Settings for Transmitter
        Dictionary<int,SettingsTx> P_TX = new Dictionary<int,SettingsTx>();
        //string P_TxIPAddress;
        int P_CommScanTime;
        Thompson.Tx TX = new Thompson.Tx();
        
        //Settings for PLC
        string P_PLCIPAddress;
        PlcComm PLC = new PlcComm();
        List<ComboBox> AllComboBoxWritePLC = new List<ComboBox>();

        //Instance for writing logs from this file
        LogData log = new LogData();
        int retryAttempts = 8;

        int txNumber;

        public StartWindow()
        {
            //Step 1: Init the GUI

            log.Write(string.Format("Started Application {0}", swVersion()));

            InitializeComponent();

            initInterface();
        }

        private void initInterface()
        {   /******************************/
            /* Initialize the Application */
            /******************************/
            //Step 1: Read the settings file
            log.Write("Beginning to read Settings File...");
            lblGeneralStatus.Text = "Beginning to read Settings File...";
            lblGeneralStatus.ForeColor = Color.Black;
            bool l_settingsReadSuccess = false;
            lblSettingsDisplay.Text = readSettings(ref l_settingsReadSuccess);
            log.Write(lblSettingsDisplay.Text);
            if (l_settingsReadSuccess == false)
            {
                lblGeneralStatus.Text = "Settings file could not be read. Check log!";
                return;
            }
            string ourVersion = string.Empty;
            System.Reflection.Assembly assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly();
            if (assemblyInfo != null)
                lblVersion.Text = string.Format("{0}", assemblyInfo.GetName().Version.ToString());

            //Step 2: Set the TX IP Addresses
            TX.IPaddress = P_TX[txNumber].IPAddress;
 
            //Step 3: Set the PLC IP Address
            PLC.PlcIpAddress = P_PLCIPAddress;
            PLC.CommEnabled = true;
            
            //Step 5: Set the Communication timer and enable
            tmrScanPLC.Interval = 250; 
            tmrScanTX.Interval = P_CommScanTime;
            tmrScanPLC.Enabled = true;
            tmrAlarm.Interval = 2000;
            tmrAlarm.Enabled = true;
                
            if (TX.IPaddress.Length > 6)
            {
                TX.CommEnabled = true;
                retryAttempts = 2;
                tmrScanTX.Enabled = true;
                chBoxTxAutoLog();
                UpdateGUIbuttons();
            }
            else lblTxStatus.Text = "No IP address found";

            lblGeneralStatus.Text = "Initializing communications...";
        }

        private void tmrScanPLC_Tick(object sender, EventArgs e)
        {
            PLC.ReadWrite();

            if (PLC.CommEnabled == false)
            {
                lblGeneralStatus.Text = "Could not communicate with PLC!";
                lblGeneralStatus.ForeColor = Color.Red;
            }
            else lblGeneralStatus.Text = "";

            //Print Plc Request to GUI
            showPlcRequests();
        }
        
        private void tmrScanTX_Tick(object sender, EventArgs e)
        {
            //This is the main execution loop
            
            //Setup for TX status messages
            StringWriter strTX = new StringWriter();

            if (PLC.CommEnabled != true) return;

            /***********************/
            /*  1.) Get TX Status  */
            /***********************/

            if (retryAttempts >= 1)
            {
                grpBoxTX.BackColor = Color.Transparent;
                TX.GetSnmpStatus();
            }
            else grpBoxTX.BackColor = Color.Red;

            if (TX.CommEnabled == false)
            {
                loopErrorRetry();
                strTX.WriteLine("Could not communicate with TX");
            }
            else
            {
                //Assumed normal status was received
                //Write Heating state back to PLC
                PLC.WriteToPlc(PlcComm.B_Write.HeatingOnTx6, TX.GetHeating());

                //Update text in GUI
                strTX.WriteLine(TX.ReadStatusString(chBoxTxAuto.Checked));

                //Update buttons in GUI
                UpdateGUIbuttons();

                //Update txState and log if changed
                TX.GetTxState(tmrLogMeters);

                //Update Meters
                Update_Meters();
            }


            /******************************/
            /*  2.) PLC Data was Received */
            /******************************/

            //Copy to local variable
            RequestToTx req = PLC.TxRequest();

            if (req != null)
            {
                //Send request to TX
                if (req.Channel > 0)
                {
                    
                    //Set Modulation
                    if (req.GenModulation == true)
                    {
                        TX.SetCmdModulation(P_TX[txNumber].ModulationGenerator[req.ModulationRequest]);
                        lblGenMod.Visible = true;
                    }
                    else
                    {
                        TX.SetCmdModulation(P_TX[txNumber].ModulationNormal[req.ModulationRequest]);
                        lblGenMod.Visible = false;
                    }
                    //Set Power
                    if (req.GenPower == true)
                    {
                        TX.SetPowerLevel(P_TX[txNumber].PowerLevelGenerator[req.PowerRequest]);
                        lblGenPwr.Visible = true;
                    }
                    else
                    {
                        TX.SetPowerLevel(P_TX[txNumber].PowerLevelNormal[req.PowerRequest]);
                        lblGenPwr.Visible = false;
                    }

                    //Set Command
                    TX.SetCmdTx(req.Command);

                    //Set Frequency/Channel
                    TX.SetFrequencyNumber(req.Channel);
                }
                else
                {
                    string error = (string.Format("Error in requested channel from PLC ({0})!", req.Channel));
                    log.Write(error);
                    strTX.WriteLine(error);
                }
            }

            /*********************************/
            /*  3.) Write to TX (if enabled) */
            /*********************************/
            
            if (chBoxTxAuto.Checked == true && TX.CommEnabled == true)
            {
                //Send Request to TX via SNMP if not inhibited
                TX.SetSnmpIntegers();

                //Quit if can't connect!
                if (TX.CommEnabled == false)
                {
                    if (loopErrorRetry() == true)
                    {
                        strTX.WriteLine("Could not communicate with TX!");
                    }
                }
            }
                        
            //Write status to GUI for TX's
            lblTxStatus.Text = strTX.ToString();
            
            //lblGeneralStatus.Text = "";
            if (TX.CommEnabled == true) retryAttempts = 3;
        }

         private bool loopErrorRetry()
        {
            //An error was caught 
            //decrement retryAttempts
            retryAttempts--;

            if (retryAttempts >= 1)
            {
                log.Write(string.Format("Loop Error for TX {1}. Retry Attempts: {0}", retryAttempts.ToString(), txNumber));
                return true;
            }
            else
            {
                log.Write(string.Format("Loop Error for TX {1}. Retry Attempts: {0}  Abort execution.", retryAttempts.ToString(), txNumber));
                return false;
            }    
        }

        public void showPlcRequests()
        {
            StringWriter plcDisplay = new StringWriter();
            plcDisplay.WriteLine("Requests read from PLC / ARC+\nTX Requests:");

            try
            {
                plcDisplay.WriteLine(reqToString(PLC.TxRequest()));
            }
            catch
            {
                plcDisplay.WriteLine("TX Data not available");
            }
            
            lblPlcRequest.Text = plcDisplay.ToString();
        }

        private string reqToString(RequestToTx req)
        {
            StringWriter strReq = new StringWriter();
            strReq.WriteLine("Channel: {0}", req.Channel.ToString());
            strReq.WriteLine("Modulation: {0}", req.ModulationRequest.ToString());
            strReq.WriteLine("Power: {0}", req.PowerRequest.ToString());
            strReq.WriteLine("Command: {0}", req.Command.ToString());
            strReq.WriteLine("Use Modulation setting for Generator: {0}", req.GenModulation.ToString());
            strReq.WriteLine("Use Power setting for Generator: {0}", req.GenPower.ToString());
            strReq.WriteLine("Heater has been on for minimum time: {0}",req.HeatOnForMinTime.ToString());
            return strReq.ToString();
        }

        private string readSettings(ref bool success_b)
        {
            //init success as false
            success_b = false;

            //New string for returning the results
            StringWriter settingstext = new StringWriter();
            settingstext.WriteLine("Settings loaded from file: ThompsonTxInterface.exe.config");

            foreach (string key in ConfigurationManager.AppSettings)
            {
                //Get the value of the parameter in the settings file
                string value = ConfigurationManager.AppSettings[key];
                //split the parameter name into an array using the '_' character
                string[] keysplit = key.Split('_');
                
                //Go here if the parameter is associated with a Transmitter
                if (keysplit[0].Equals("TX", StringComparison.CurrentCultureIgnoreCase))
                {
                    //TX Number is in 2nd parse
                    txNumber = Convert.ToInt32(keysplit[1]);
                    PLC.TxNum = txNumber;
                    //Check if TX exists yet; add new Tx to settings if does not exist
                    if (P_TX.ContainsKey(txNumber) == false)
                    {
                        //Create a new dummy class with default values that can be checked later
                        P_TX.Add(txNumber, new SettingsTx   {
                                    Name = keysplit[0] + keysplit[1],
                                    IPAddress = null,
                                    ModulationNormal = new Thompson.Tx.E_CommandModulationMode[] 
                                            {Thompson.Tx.E_CommandModulationMode.Unknown, 
                                                Thompson.Tx.E_CommandModulationMode.Unknown, 
                                                Thompson.Tx.E_CommandModulationMode.Unknown, 
                                                Thompson.Tx.E_CommandModulationMode.Unknown},
                                    ModulationGenerator = new Thompson.Tx.E_CommandModulationMode[]
                                            {Thompson.Tx.E_CommandModulationMode.Unknown, 
                                                Thompson.Tx.E_CommandModulationMode.Unknown, 
                                                Thompson.Tx.E_CommandModulationMode.Unknown, 
                                                Thompson.Tx.E_CommandModulationMode.Unknown},
                                    PowerLevelNormal = new int[] {999, 999, 999, 999},
                                    PowerLevelGenerator = new int[] {999,999,999,999} });
                    }

                    grpBoxTX.Text = string.Format("TX {0}", txNumber);

                    if (keysplit[2].Equals("Modulation", StringComparison.CurrentCultureIgnoreCase))
                    {
                        //This is a modulation type - add it to the appropriate array
                        Thompson.Tx.E_CommandModulationMode modtype = (Thompson.Tx.E_CommandModulationMode)Convert.ToInt32(value);
                        if (keysplit[4].Equals("Normal", StringComparison.CurrentCultureIgnoreCase))
                        {
                            P_TX[txNumber].ModulationNormal[Convert.ToInt32(keysplit[3])] = modtype;
                        }
                        else if (keysplit[4].Equals("Generator", StringComparison.CurrentCultureIgnoreCase))
                        {
                            P_TX[txNumber].ModulationGenerator[Convert.ToInt32(keysplit[3])] = modtype;
                        }
                        else
                        {
                            //Invalid Modulation
                            string error = string.Format("Error loading setting {0}", key);
                            return error;
                        }
                    }
                    else if (keysplit[2].Equals("Power", StringComparison.CurrentCultureIgnoreCase))
                    {
                        //This is a modulation type - add it to the appropriate array
                        int powerlevel = Convert.ToInt32(value);
                        if (keysplit[4].Equals("Normal", StringComparison.CurrentCultureIgnoreCase))
                        {
                            P_TX[txNumber].PowerLevelNormal[Convert.ToInt32(keysplit[3])] = powerlevel;
                        }
                        else if (keysplit[4].Equals("Generator", StringComparison.CurrentCultureIgnoreCase))
                        {
                            P_TX[txNumber].PowerLevelGenerator[Convert.ToInt32(keysplit[3])] = powerlevel;
                        }
                        else
                        {
                            //Invalid Modulation
                            string error = string.Format("Error loading setting {0}", key);
                            return error;
                        }
                    }
                    else if (keysplit[2].Equals("IPAddress", StringComparison.CurrentCultureIgnoreCase))
                    {
                        //Here is the IP address for the transmitter
                        P_TX[txNumber].IPAddress = value;
                    }
                    else
                    {
                        string error = string.Format("Error loading setting {0}", key);
                        return error;
                    }
                }
                else if (keysplit[0].Equals("PLC", StringComparison.CurrentCultureIgnoreCase))
                {
                    //Go here if the parameter is for the PLC
                    if (keysplit[1].Equals("IPAddress", StringComparison.CurrentCultureIgnoreCase))
                    {
                        //This is the PLC IP Address
                        P_PLCIPAddress = value;
                    }
                    else
                    {
                        string error = string.Format("Error loading setting {0}", key);
                        return error;
                    }
                }
                else if (keysplit[0].Equals("CommunicationScanTime", StringComparison.CurrentCultureIgnoreCase))
                {
                    //Load Scan Time here
                    P_CommScanTime = Convert.ToInt32(value);
                }
                else if (keysplit[0].Equals("Options", StringComparison.CurrentCultureIgnoreCase))
                { }
                else
                {
                    string error = string.Format("Error loading setting {0}", key);
                    return error;
                }
            }

            //Check if Communication Settings are defined
            if (P_CommScanTime == 0)
            {
                string error = ("Scan Time not defined!");
                return error;
            }
            else
            {
                settingstext.WriteLine("Scan Time: {0} ms", P_CommScanTime.ToString());
            }
            if (P_PLCIPAddress == null) 
            { 
                string error = ("PLC IP Address not defined!"); 
                return error; 
            } 
            else 
            { 
                settingstext.WriteLine("PLC IP Address: {0}", P_PLCIPAddress); 
            } 

            //Check if all otherTX  settings are defined
            SettingsTx newtxparam = P_TX[txNumber];
            {
                if (newtxparam.IPAddress == null)
                {
                    string error = string.Format("IP Address not defined!({0})", newtxparam.Name);
                    return error;
                }
                else
                {
                    settingstext.WriteLine("TX IP Address: {0}", newtxparam.IPAddress);
                }

                settingstext.Write("Modulation Normal: ");
                for (int i = 0; i < newtxparam.ModulationNormal.Length; i++)
                {
                    if (newtxparam.ModulationNormal[i] == Thompson.Tx.E_CommandModulationMode.Unknown)
                    {
                        string error = string.Format("Modulation Normal {0} type not defined!({1})", i.ToString(), newtxparam.Name);
                        return error;
                    }
                    else
                    {
                        settingstext.Write("[{0} = {1}] ", i.ToString(), newtxparam.ModulationNormal[i].ToString());
                    }
                }
                settingstext.Write("\nModulation on Generator: ");
                for (int i = 0; i < newtxparam.ModulationGenerator.Length; i++)
                {
                    if (newtxparam.ModulationGenerator[i] == Thompson.Tx.E_CommandModulationMode.Unknown)
                    {
                        string error = string.Format("Modulation Generator {0} type not defined!({1})", i.ToString(), newtxparam.Name);
                        return error;
                    }
                    else
                    {
                        settingstext.Write("[{0} = {1}] ", i.ToString(), newtxparam.ModulationGenerator[i].ToString());
                    }
                }
                settingstext.Write("\nPower Normal: ");
                for (int i = 0; i < newtxparam.PowerLevelNormal.Length; i++)
                {
                    if (newtxparam.PowerLevelNormal[i] == 999)
                    {
                        string error = string.Format("Power Level Normal {0} type not defined!({1})", i.ToString(), newtxparam.Name);
                        return error;
                    }
                    else
                    {
                        settingstext.Write("[{0} = {1}] ", i.ToString(), newtxparam.PowerLevelNormal[i].ToString());
                    }
                }
                settingstext.Write("\nPower on Generator: ");
                for (int i = 0; i < newtxparam.PowerLevelGenerator.Length; i++)
                {
                    if (newtxparam.PowerLevelGenerator[i] == 999)
                    {
                        string error = string.Format("Power Level Generator {0} type not defined!({1})", i.ToString(), newtxparam.Name);
                        return error;
                    }
                    else
                    {
                        settingstext.Write("[{0} = {1}] ", i.ToString(), newtxparam.PowerLevelGenerator[i].ToString());
                    }
                }

            }

            //Settings were read successfully if it gets here
            success_b = true;
            return settingstext.ToString();     
        }

        private void StartWindow_FormClosed(object sender, FormClosedEventArgs e)
        {
            log.Write("Application closed");
        }

        private void btnRestart_Click(object sender, EventArgs e)
        {
            log.Write("Application is restarted");
            initInterface();
        }

        private void UpdateGUIbuttons()
        {
                //Read current values in PLC and try it for errors
                RequestToTx txReq = PLC.TxRequest();

                try
                {
                    int x = txReq.Channel;
                }
                catch
                {
                    return;
                }

                // Set text and color for TX Remote/Local button
                this.btnTXRemLocal.Text = TX.GetCurrentValue("OperatorObj");
                if (this.btnTXRemLocal.Text == "Remote") this.btnTXRemLocal.BackColor = Color.LimeGreen; else this.btnTXRemLocal.BackColor = Color.Red;
                
                // Set color for TX Adaptation button
                if (TX.GetCurrentValue("SwitchOverModeObj") == "Auto") this.btnTXAdaptation.BackColor = Color.LimeGreen; else this.btnTXAdaptation.BackColor = Color.Red;

                // Set color for TX Off, Filaments, and ON buttons
                string CmdTxObj = TX.GetCurrentValue("CmdTxObj");
                if (CmdTxObj == "GeneralShutdown") this.btnTXOff.BackColor = Color.LimeGreen; else this.btnTXOff.BackColor = Color.Transparent;
                if (CmdTxObj == "HeatingOn" || CmdTxObj == "CircuitBreakerOn" || CmdTxObj == "GeneralOn") this.btnTXFils.BackColor = Color.LimeGreen; else this.btnTXFils.BackColor = Color.Transparent;
                if (CmdTxObj == "GeneralOn") this.btnTXON.BackColor = Color.LimeGreen; else this.btnTXON.BackColor = Color.Transparent;

                // Set the text on modulation type buttons depending on generator state
                if (txReq.GenModulation == true)
                {
                    btnTXMod0.Text = Convert.ToString(P_TX[txNumber].ModulationGenerator[0]);
                    btnTXMod1.Text = Convert.ToString(P_TX[txNumber].ModulationGenerator[1]);
                    btnTXMod2.Text = Convert.ToString(P_TX[txNumber].ModulationGenerator[2]);
                    btnTXMod3.Text = Convert.ToString(P_TX[txNumber].ModulationGenerator[3]);
                }
                else
                {
                    btnTXMod0.Text = Convert.ToString(P_TX[txNumber].ModulationNormal[0]);
                    btnTXMod1.Text = Convert.ToString(P_TX[txNumber].ModulationNormal[1]);
                    btnTXMod2.Text = Convert.ToString(P_TX[txNumber].ModulationNormal[2]);
                    btnTXMod3.Text = Convert.ToString(P_TX[txNumber].ModulationNormal[3]);
                }

                // Set the text on power level buttons depending on generator state
                if (txReq.GenPower == true)
                {
                    btnTXPwr0.Text = (Convert.ToString(P_TX[txNumber].PowerLevelGenerator[0]) + "%");
                    btnTXPwr1.Text = (Convert.ToString(P_TX[txNumber].PowerLevelGenerator[1]) + "%");
                    btnTXPwr2.Text = (Convert.ToString(P_TX[txNumber].PowerLevelGenerator[2]) + "%");
                    btnTXPwr3.Text = (Convert.ToString(P_TX[txNumber].PowerLevelGenerator[3]) + "%");
                }
                else
                {
                    btnTXPwr0.Text = (Convert.ToString(P_TX[txNumber].PowerLevelNormal[0]) + "%");
                    btnTXPwr1.Text = (Convert.ToString(P_TX[txNumber].PowerLevelNormal[1]) + "%");
                    btnTXPwr2.Text = (Convert.ToString(P_TX[txNumber].PowerLevelNormal[2]) + "%");
                    btnTXPwr3.Text = (Convert.ToString(P_TX[txNumber].PowerLevelNormal[3]) + "%");
                }

                // Set color on the Power level buttons to indicate active level
                btnTXPwr0.BackColor = Color.Transparent;
                btnTXPwr1.BackColor = Color.Transparent;
                btnTXPwr2.BackColor = Color.Transparent;
                btnTXPwr3.BackColor = Color.Transparent;

                switch (txReq.PowerRequest)
                {
                    case 0:
                        btnTXPwr0.BackColor = Color.LimeGreen;
                        break;
                    case 1:
                        btnTXPwr1.BackColor = Color.LimeGreen;
                        break;
                    case 2:
                        btnTXPwr2.BackColor = Color.LimeGreen;
                        break;
                    case 3:
                        btnTXPwr3.BackColor = Color.LimeGreen;
                        break;
                }

                // Set color on the Modulation type buttons to indicate active type
                btnTXMod0.BackColor = Color.Transparent;
                btnTXMod1.BackColor = Color.Transparent;
                btnTXMod2.BackColor = Color.Transparent;
                btnTXMod3.BackColor = Color.Transparent;

                switch (txReq.ModulationRequest)
                {
                    case 0:
                        btnTXMod0.BackColor = Color.LimeGreen;
                        break;
                    case 1:
                        btnTXMod1.BackColor = Color.LimeGreen;
                        break;
                    case 2:
                        btnTXMod2.BackColor = Color.LimeGreen;
                        break;
                    case 3:
                        btnTXMod3.BackColor = Color.LimeGreen;
                        break;
                }

                // Set color on active channel button
                btnTXCh1.BackColor = Color.Transparent;
                btnTXCh2.BackColor = Color.Transparent;
                btnTXCh3.BackColor = Color.Transparent;
                btnTXCh4.BackColor = Color.Transparent;
                btnTXCh5.BackColor = Color.Transparent;
                btnTXCh6.BackColor = Color.Transparent;
                btnTXCh7.BackColor = Color.Transparent;
                btnTXCh8.BackColor = Color.Transparent;
                btnTXCh9.BackColor = Color.Transparent;
                btnTXCh10.BackColor = Color.Transparent;
                btnTXCh11.BackColor = Color.Transparent;
                btnTXCh12.BackColor = Color.Transparent;
                btnTXCh13.BackColor = Color.Transparent;
                btnTXCh14.BackColor = Color.Transparent;
                btnTXCh15.BackColor = Color.Transparent;

                switch (txReq.Channel)
                {
                    case 1:
                        btnTXCh1.BackColor = Color.LimeGreen;
                        break;
                    case 2:
                        btnTXCh2.BackColor = Color.LimeGreen;
                        break;
                    case 3:
                        btnTXCh3.BackColor = Color.LimeGreen;
                        break;
                    case 4:
                        btnTXCh4.BackColor = Color.LimeGreen;
                        break;
                    case 5:
                        btnTXCh5.BackColor = Color.LimeGreen;
                        break;
                    case 6:
                        btnTXCh6.BackColor = Color.LimeGreen;
                        break;
                    case 7:
                        btnTXCh7.BackColor = Color.LimeGreen;
                        break;
                    case 8:
                        btnTXCh8.BackColor = Color.LimeGreen;
                        break;
                    case 9:
                        btnTXCh9.BackColor = Color.LimeGreen;
                        break;
                    case 10:
                        btnTXCh10.BackColor = Color.LimeGreen;
                        break;
                    case 11:
                        btnTXCh11.BackColor = Color.LimeGreen;
                        break;
                    case 12:
                        btnTXCh12.BackColor = Color.LimeGreen;
                        break;
                    case 13:
                        btnTXCh13.BackColor = Color.LimeGreen;
                        break;
                    case 14:
                        btnTXCh14.BackColor = Color.LimeGreen;
                        break;
                    case 15:
                        btnTXCh15.BackColor = Color.LimeGreen;
                        break;
                }
        }

        /// <summary>
        /// Return the current version. If running the deployed version, returns that version number,
        /// otherwise returns the assembly version.
        /// </summary>
        /// <returns>Version number</returns>
        private string swVersion()
        {
            string ourVersion = string.Empty;
            
            string assemName = Assembly.GetEntryAssembly().GetName().Name.ToString(); 
            //if running the deployed application, you can get the version
            //  from the ApplicationDeployment information. If you try
            //  to access this when you are running in Visual Studio, it will not work.
            
            if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                ourVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
            else
            {
                System.Reflection.Assembly assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly();
                if (assemblyInfo != null)
                    ourVersion = string.Format("{0}", assemblyInfo.GetName().Version.ToString());
            }
            return string.Format("{0} Version: {1}",assemName,ourVersion);
        }

        private class SettingsTx
        {
            public Thompson.Tx.E_CommandModulationMode[] ModulationNormal { get; set; }
            public Thompson.Tx.E_CommandModulationMode[] ModulationGenerator { get; set; }
            public int[] PowerLevelNormal { get; set; }
            public int[] PowerLevelGenerator { get; set; }
            public string IPAddress { get; set; }
            public string Name { get; set; }
        }

        private void chBoxTxAuto_CheckedChanged(object sender, EventArgs e)
        {
            if (chBoxTxAuto.Checked == true) 
            {
                chBoxTxAuto.BackColor = Color.LimeGreen;
                chBoxTxAuto.Text = "Auto";
            }
            else
            {
                chBoxTxAuto.BackColor = Color.Red;
                chBoxTxAuto.Text = "Manual";
            }
            chBoxTxAutoLog();
        }

        private void chBoxTxAutoLog()
        {
            log.Write(string.Format("Enable sending of requests to TX {1}: {0}", chBoxTxAuto.Checked.ToString(),txNumber));
        }

         private void btnTXCtrlEnable_Click(object sender, EventArgs e)
        {
            tmrTXControlEnable.Enabled = true;
            btnTXCtrlEnable.BackColor = Color.Red;
        }

        private void tmrTXControl_Tick(object sender, EventArgs e)
        {
            tmrTXControlEnable.Enabled = false;
            btnTXCtrlEnable.BackColor = Color.Transparent;
        }

         private void btnTXOff_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;
            
            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new command
            txReq.Command = (Thompson.Tx.E_CommandTx)Enum.Parse(typeof(Thompson.Tx.E_CommandTx), "GeneralShutdown");

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXFils_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;
            
            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new command
            txReq.Command = (Thompson.Tx.E_CommandTx)Enum.Parse(typeof(Thompson.Tx.E_CommandTx), "HeatingOn");

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXON_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;
            
            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new command
            txReq.Command = (Thompson.Tx.E_CommandTx)Enum.Parse(typeof(Thompson.Tx.E_CommandTx), "GeneralOn");

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh1_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh1.BackColor = Color.Red;
            
            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 1;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh2_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh2.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 2;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh3_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh3.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 3;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh4_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh4.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 4;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh5_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh5.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 5;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh6_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh6.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 6;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh7_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh7.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 7;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh8_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh8.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 8;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh9_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh9.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 9;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh10_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh10.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 10;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh11_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh11.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 11;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh12_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh12.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 12;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh13_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh13.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 13;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh14_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh14.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 14;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXCh15_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXCh15.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new channel
            txReq.Channel = 15;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXPwr0_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXPwr0.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new power
            txReq.PowerRequest = 0;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXPwr1_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXPwr1.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new power
            txReq.PowerRequest = 1;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);

        }

        private void btnTXPwr2_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXPwr2.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new power
            txReq.PowerRequest = 2;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXPwr3_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXPwr3.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new power
            txReq.PowerRequest = 3;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXMod0_Click(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXMod0.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new Mod type
            txReq.ModulationRequest = 0;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXMod1_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXMod1.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new Mod type
            txReq.ModulationRequest = 1;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXMod2_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXMod2.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new Mod type
            txReq.ModulationRequest = 2;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnTXMod3_Click_1(object sender, EventArgs e)
        {
            if (!tmrTXControlEnable.Enabled) return;

            btnTXMod3.BackColor = Color.Red;

            //Read current values in PLC
            RequestToTx txReq = PLC.TxRequest();

            //Set new Mod type
            txReq.ModulationRequest = 3;

            //Send requests back to PLC
            PLC.OverrideBurk(txReq);
        }

        private void btnEditConfig_Click(object sender, EventArgs e)
        {
            string cfgFile = ".\\ThompsonTxInterface.exe.config";
            System.Diagnostics.Process.Start(@"notepad.exe", cfgFile);
        }

        // The Tx returns a value of E_Status.unknown if it has internal communication issues
        // To not alarm when this is happening, check the checkbox on the settings tab
        private void chkbxUnknownStatusAlarm_CheckedChanged(object sender, EventArgs e)
        {
            TX.DisableUnknownStatusAlarm = chkbxDisableUnknownStatusAlarm.Checked;
        }

        private void lblVSWRVal_Click(object sender, EventArgs e)
        {

        }

        private void Update_Meters()
        {
            double[] Values = TX.MeterValues();
                if (Convert.ToInt16(Values[0]) > pBarAudio.Maximum) pBarAudio.Value = pBarAudio.Maximum; else pBarAudio.Value = Convert.ToInt16(Values[0]);
                if (Convert.ToInt16(Values[1]) > pBarVmain.Maximum) pBarVmain.Value = pBarVmain.Maximum; else pBarVmain.Value = Convert.ToInt16(Values[1]);
                if (Convert.ToInt16(Values[2]) > pBarPwr.Maximum) pBarPwr.Value = pBarPwr.Maximum; else pBarPwr.Value = Convert.ToInt16(Values[2]);
                if (Convert.ToInt16(Values[3] * 10) > pBarVSWR.Maximum) pBarVSWR.Value = pBarVSWR.Maximum; else pBarVSWR.Value = Convert.ToInt16(Values[3] * 10);
                if (Convert.ToInt16(Values[4] * 10) > pBarPref.Maximum) pBarPref.Value = pBarPref.Maximum; else pBarPref.Value = Convert.ToInt16(Values[4] * 10);
                if (Convert.ToInt16(Values[5] * 10) > pBarTempDelta.Maximum) pBarTempDelta.Value = pBarTempDelta.Maximum; else pBarTempDelta.Value = Convert.ToInt16(Values[5]* 10);
                if (Convert.ToInt16(Values[6]) > pBarVgrid.Maximum) pBarVgrid.Value = pBarVgrid.Maximum; else pBarVgrid.Value = Convert.ToInt16(Values[6]);
                if (Convert.ToInt16(Values[7] * 10) > pBarIgrid.Maximum) pBarIgrid.Value = pBarIgrid.Maximum; else pBarIgrid.Value = Convert.ToInt16(Values[7] * 10);
                if (Convert.ToInt16(Values[8]) > pBarVanode.Maximum) pBarVanode.Value = pBarVanode.Maximum; else pBarVanode.Value = Convert.ToInt16(Values[8]);
                if (Convert.ToInt16(Values[9]) > pBarIanode.Maximum) pBarIanode.Value = pBarIanode.Maximum; else pBarIanode.Value = Convert.ToInt16(Values[9]);
                if (Convert.ToInt16(Values[10]) > pBarIscreen.Maximum) pBarIscreen.Value = pBarIscreen.Maximum; else pBarIscreen.Value = Convert.ToInt16(Values[10]);

            lblIscreenVal.Text = (Values[10].ToString() + " A");
            lblAudioVal.Text = (Values[0].ToString() + " %");
            lblVmainVal.Text = (Values[1].ToString() + " V");
            lblPwrVal.Text = (Values[2].ToString() + " kW");
            lblVSWRVal.Text = (Values[3].ToString());
            lblPrefVal.Text = (Values[4].ToString() + " kW");
            lblTempDeltaVal.Text = (Values[5].ToString() + " ⁰C");
            lblVgridVal.Text = (Values[6].ToString() + " V");
            lblIgridVal.Text = (Values[7].ToString() + " A");
            lblVanodeVal.Text = (Values[8].ToString() + " V");
            lblIanodeVal.Text = (Values[9].ToString() + " A");
        }

        private void LogMeters()
        {
            try
            {
                double[] Values = TX.MeterValues();
                log.Write(string.Format("\nAudio Level: {0}%  \tMains Voltage:  {1}V", Values[0], Values[1]));
                log.Write(string.Format("Fwd Power:   {0}kW \tReflected Pwr:  {1}kW \tVSWR: {2}", Values[2], Values[4], Values[3]));
                log.Write(string.Format("Tube T∆:     {0}⁰C \tScreen Current: {1}A", Values[5], Values[10]));
                log.Write(string.Format("Grid Volts:  {0}V  \tGrid Current:   {1}A", Values[6], Values[7]));
                log.Write(string.Format("Anode Volts: {0}V  \tAnode Current:  {1}A\n", Values[8], Values[9]));
            }
            catch { log.Write("Can't log meters"); }
        }

        private void tmrLogMeters_Tick(object sender, EventArgs e)
        {
            LogMeters();
            tmrLogMeters.Interval = 900000;
        }

        private void tmrAlarm_Tick(object sender, EventArgs e)
        {
            //Write Alarm state back to PLC - alarm if Thompson ignores requests or if Automatic mode not enabled
            bool plcAlarm = (chBoxTxAuto.Checked == false || TX.GetAlarm(chBoxTxAuto.Checked));
            PLC.WriteToPlc(PlcComm.B_Write.ErrorTx6, plcAlarm);
        }
        
    }
}
